package connector;

import java.awt.Dimension;

import java.awt.Image;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;

import java.net.URL;

import java.net.URLConnection;
import java.net.URLEncoder;

import java.util.Properties;

import oracle.lbs.mapclient.MapViewer;


public class Connector 
{
    private MapConfig config = null;
    
    private MapViewer map = null;   //the core class for interacting with 
                                    //a MapViewer server
      
    private Dimension viewportSize = null;
    
    private Image mapImage = null;
        
    private double mapCenterX;
    private double mapCenterY;
    private int    mapCenterSrid;
    private long   mapScale;
    
    public Connector() throws Exception {
	
		setupConfig();
       
		
		
        map = new MapViewer(config.getMapViewerUrl());
        
        map.setDataSourceName(config.getDataSourceName());

        //so that pre-generated map tiles can be utilized
        map.setSnapToCachedZoomLevel(true);
        
        map.addMapTileTheme("Map tile layer", 
                            config.getDataSourceName(), 
                            config.getMapTileLayerName(),
                            true);        
        
        mapCenterX = config.getInitX();
        mapCenterY = config.getInitY();
        mapCenterSrid = config.getInitSrid();
        mapScale = config.getInitMapScale();
        
        map.setImageFormat(MapViewer.FORMAT_RAW_COMPRESSED);
        
        map.setCenterAndScaleWithSRID(mapCenterX, mapCenterY, mapScale, mapCenterSrid);
        
        setViewportSize(new Dimension(740,685));
        reloadMap();
    }

	public AddressInfo[] getAddresses(String pattern){
        try {
            System.out.println("doQuery:");
            String[][] myTable = map.doQuery(config.getDataSourceName(), "SELECT FENAME, FETYPE, FEDIRP, FEDIRS, FRADDL, TOADDL, FRADDR, TOADDR FROM Spatial WHERE FENAME LIKE '%"+pattern+"%' AND (FETYPE='St' OR FETYPE='Ave' OR FETYPE='Blvd')");
			AddressInfo[] ai = new AddressInfo[myTable.length - 1];
			for (int i = 1; i < myTable.length; i++)
				ai[i-1] = new AddressInfo(myTable[i][0],myTable[i][1],myTable[i][2],myTable[i][3],Integer.valueOf(myTable[i][4]).intValue(),Integer.valueOf(myTable[i][5]).intValue(),Integer.valueOf(myTable[i][6]).intValue(), Integer.valueOf(myTable[i][7]).intValue());
			return ai;
		}catch(Exception e) {
            System.out.println("Error: " + e.getMessage());
        }
		return null;
	}
	
    /**
     * Set the map center point to be the given longitude/latitude.
     * This is a convenient method to override the default center point
     * specified in the mapconfig properties file.
     * 
     * 
     * @param lon  the longitude
     * @param lat  the latitude
     */
    public synchronized void setMapCenterLatLon(double lon, double lat) {
        map.setCenterAndScaleWithSRID(lon, lat, mapScale, 8307);
        reloadMap();
    }
    
    public Dimension getViewportSize() {
        return viewportSize;
    }
    
    public synchronized void setViewportSize(Dimension _viewportSize) {
        
       // if(viewportSize!=null && viewportSize.equals(_viewportSize))
        //    return;

        viewportSize = _viewportSize;       
        map.setDeviceSize(viewportSize);
        if(mapImage!=null)
           reloadMap();
    }


    public synchronized Image getMapImage() {
        return mapImage;
    }
    
    public synchronized void reloadMap() 
    {
        if(viewportSize==null)
            return;                
        try{
            boolean result = map.run();
            if(result) {              
               mapImage =  map.getGeneratedMapImage();
            }
        }catch(Exception e) 
        {
            System.err.println("exception when loading map.");
            e.printStackTrace(System.err);
        }        
    }
    
    /**
     * Recenters the map display to the specified pixel location
     * @param x  pixel x
     * @param y  pixel y
     */
    public synchronized void recenter(int x, int y) {
        try{
            boolean res = map.pan(x,y);
            if(res)
                mapImage =  map.getGeneratedMapImage();
        }catch(Exception e) {
            e.printStackTrace(System.err);
        }                
    }

    public synchronized void panNorth() {
        int x = (int) (viewportSize.getWidth()/2 );
        int y = (int) (viewportSize.getHeight()*0.33333);
        try{
            boolean res = map.pan(x,y);
            if(res)
                mapImage =  map.getGeneratedMapImage();
        }catch(Exception e) {
            e.printStackTrace(System.err);
        }        
    }
    
    public synchronized void panSouth(){
        int x = (int) (viewportSize.getWidth()/2 );
        int y = (int) (viewportSize.getHeight()*0.66666);
        try{
            boolean res = map.pan(x,y);
            if(res)
                mapImage =  map.getGeneratedMapImage();
        }catch(Exception e) {
            e.printStackTrace(System.err);
        }
    }
    
    public synchronized void panEast(){
        int x = (int) (viewportSize.getWidth()*0.66666 );
        int y = (int) (viewportSize.getHeight()/2);
        try{
            boolean res = map.pan(x,y);
            if(res)
            {
                mapImage =  map.getGeneratedMapImage();
            }
        }catch(Exception e) {
            e.printStackTrace(System.err);
        }        
        
    }
    
    public synchronized void panWest(){
        int x = (int) (viewportSize.getWidth()*0.33333 );
        int y = (int) (viewportSize.getHeight()/2);
        try{
            boolean res = map.pan(x,y);
            if(res)
                mapImage =  map.getGeneratedMapImage();
        }catch(Exception e) {
            e.printStackTrace(System.err);
        }        
                
    }
    
    public synchronized void zoomIn(){
        try{
            boolean res = map.zoomIn(1.5);
            if(res)
                mapImage = map.getGeneratedMapImage();
        }catch(Exception e) {
            e.printStackTrace(System.err);
        }
    }
    
    public synchronized void zoomOut(){
        try{
            boolean res = map.zoomOut(1.5);
            if(res)
                mapImage = map.getGeneratedMapImage();
        }catch(Exception e) {
            e.printStackTrace(System.err);
        }
    }
	
	public void setupConfig() 
    throws Exception{  
		config = new MapConfig();
        URL url = Connector.class.getResource("mapconfig.properties");
        Properties p = new Properties();
        InputStream ism = url.openStream();
        p.load(ism);
        config = MapConfig.loadConfigFromProperties(p);
     
    }
     
}

/*TLID		121539627
FNODE		31430
TNODE		31326
LENGTH		.09398
FEDIRP		null
FENAME		Middle
FETYPE		Rd
FEDIRS		null
CFCC		A41
FRADDL		66
TOADDL		2
FRADDR		67
TOADDR		1
ZIPL		02650
ZIPR		02650
CENSUS1		0
CENSUS2		0
CFCC1		A
CFCC2		A4
SOURCE		J
GEOMETRY	null*/

